package translate;

import tree.BINOP;
import tree.BasicExp;
import tree.CONST;
import tree.MEM;
import tree.TEMP;

public class Translate {
	static int wordSize = 4;
	public Level currentLev; 
	private Frag frags = null, tail = null;
	
	public Translate() {
		currentLev = new Level(null, null, null);
	}
	
	public Exp simpleVar(Access a) {
		BasicExp e = new TEMP(currentLev.frame.FP());
		Level tempLev = currentLev;
		while (tempLev != a.home) {
			e = new MEM(e);
			tempLev = tempLev.parent;
		}
		return new Ex(a.acc.exp(e));
	}
	
	public Exp fieldVar(int o, Exp u) {
		return new Ex(new MEM(new BINOP(BINOP.PLUS, u.unEx(), new CONST(o * wordSize))));
	}
	
	public Exp subscriptVar(Exp i, Exp u) {
		return new Ex(new MEM(new BINOP(BINOP.PLUS, u.unEx(), new BINOP(
				BINOP.MUL, i.unEx(), new CONST(wordSize)))));
	}
	
	public void beginLevel(Level l) {
		currentLev = l;
	}
	
	public void endLevel() {
		currentLev = currentLev.parent;
	}
	
	public void addDataFrag(Level level, temp.Label lab, String str) {
		if (frags == null) {
			tail = frags = new DataFrag(str, lab, null);
		}
		else {
			tail.next = new DataFrag(str, lab, null);
			tail = tail.next;
		}
	}
	
	public void procEntryExit(Level level, Exp body, boolean ret) {
		tree.BasicStm stm = null;
		if (ret)
			stm = new tree.MOVE(new tree.TEMP(level.frame.RV()), body.unEx());
		else
			stm = body.unNx();
		if (frags == null) {
			tail = frags = new ProcFrag(level.frame.procEntryExit1(stm), level.frame, null);
		}
		else {
			tail.next = new ProcFrag(level.frame.procEntryExit1(stm), level.frame, null);
			tail = tail.next;
		}
	}
	
	public Frag getResult() {
		return frags;
	}
	
	public tree.BasicStm initialExp(tree.BasicExp var, tree.BasicExp value) {
		return new tree.MOVE(var, value);
	}
}
